package com.users.rn.rncommon.download;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.text.TextUtils;

import androidx.annotation.Nullable;

import com.users.rn.common.download.PluginFileDownloadManager;
import com.users.rn.common.init.ALHReactNativeInit;
import com.liulishuo.filedownloader.model.FileDownloadStatus;
import com.users.rn.rncommon.download.impl.DownloadListener;
import com.users.rn.rncommon.network.request.RequestListener;
import com.users.rn.rncommon.plugin.PluginInformation;
import com.users.rn.rncommon.util.RNLogger;
import com.users.rn.rncommon.util.ReactUtils;
import com.ylkj.libcommon.utils.ALog;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @Description:
 * @Author: bluce
 * @Date: 2020/12/3 11:33
 */
public class ALHPluginDownloadService extends Service {
    private AtomicBoolean isRunning;
    private String pluginId;
    private ArrayList<PluginDownloadProgressListener> mListeners = new ArrayList<>();
    private static final String TAG = "[ALHPluginDownloadService]:";

    public final static int MSG_DOWNLOADING = 0x001;
    public final static int MSG_UNZIP_FINISH = 0x002;

    public final static int TIME = 300;

    //    NoLeakHandler handler;
    protected static final int STATUS_NEVER_REQUEST = 0xA;
    protected static final int STATUS_REQUEST_START = 0xB;
    protected static final int STATUS_REQUEST_END = 0xC;
    protected int apiRequestStatus = STATUS_NEVER_REQUEST;
    private int mRetryNum = 0;
    private static final int SNATCH_API_REQUEST_WAITING_MAX_NUM = 10;
    private PluginDownloadListener pluginDownloadListener;

    public void setRNPluginDownloadListener(PluginDownloadProgressListener listener) {
        if (listener != null) {
            log("setRNPluginDownloadListener " + listener);
            if (mListeners.contains(listener)) {
                return;
            }
            mListeners.add(listener);
        }
    }

    public void cleanRNPluginDownloadListener() {
        mListeners.clear();
    }

    private void notifyListener(boolean isSuccess, String pluginId, int progress, int status) {
        if (mListeners.size() <= 0) {
            return;
        }
        if (TextUtils.isEmpty(pluginId)) {
            return;
        }
        log("notifyListener isSuccess:" + isSuccess + " ,pluginId:" + pluginId + ",status:" + status + " ,progress:" + progress);
        for (int i = 0; i < mListeners.size(); i++) {
            PluginDownloadProgressListener l = mListeners.get(i);
            if (l == null) {
                continue;
            }
            if (status == FileDownloadStatus.completed) {
                l.onSuccess(pluginId);
            } else if (status == FileDownloadStatus.progress) {
                l.onDownloading(pluginId, progress);
            } else if (status == FileDownloadStatus.error) {
                l.onFail(pluginId, status);
            }
        }
        if (PluginFileDownloadManager.INSTANCE.allTaskFinish()) {
            serviceFinished();
        }
    }


    @Override
    public void onCreate() {
        log("onCreate() " + ALHPluginDownloadService.this.toString());
        super.onCreate();
        isRunning = new AtomicBoolean(false);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (isRunning.get()) {
            String plugin = intent.getStringExtra("pluginId");
            if (!TextUtils.isEmpty(plugin)) {
                this.pluginId = plugin;
            }
            log("onStartCommand() isRunning = true, intentPluginId=" + plugin + " ,this.pluginId:" + this.pluginId);
            return START_NOT_STICKY;
        }

        try {
            pluginId = intent.getStringExtra("pluginId");

            if (pluginDownloadListener == null) {
                pluginDownloadListener = new PluginDownloadListener();
            }
            isRunning.set(true);
            log("onStartCommand() isRunning = false,pluginId=" + pluginId);
            startSnatchApiThread();
        } catch (Exception e) {
            notifyListener(false, pluginId, 0, PluginDownloadConst.FAIL_TYPE_EXCEPTION);
            serviceFinished();
            e.printStackTrace();
        }
        return START_NOT_STICKY;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return new Binder();
    }

    public class Binder extends android.os.Binder {
        public ALHPluginDownloadService getService() {
            return ALHPluginDownloadService.this;
        }
    }

    private void serviceFinished() {
        log("serviceFinished() " + ALHPluginDownloadService.this.toString());
        isRunning.set(false);
        stopSelf();
        onDestroy();
    }

    /**
     * 启动获取插件列表线程
     */
    public void startSnatchApiThread() {
        if (apiRequestStatus == STATUS_REQUEST_START) {
            return;
        }
        requestPluginInfo();
        apiRequestStatus = STATUS_REQUEST_START;
    }

    private void requestPluginInfo() {
        ALHReactNativeInit.INSTANCE.getInitInterface().requestPluginInfo(ALHPluginDownloadService.this, new RequestListener<List<PluginInformation>>() {
            @Override
            public void onSuccess(List<PluginInformation> pluginInfos) {
                apiRequestStatus = STATUS_REQUEST_END;
                log("requestUpdateInfo onSuccess content=" + pluginInfos);
                //1. 列表是否为空
                if (pluginInfos == null || pluginInfos.isEmpty()) {
                    notifyListener(false, pluginId, 0, FileDownloadStatus.error);
                    return;
                }
                if (!TextUtils.isEmpty(pluginId) && !ReactUtils.checkPluginIdExist(pluginId, pluginInfos)) {
                    notifyListener(false, pluginId, 0, FileDownloadStatus.error);
                    return;
                }
                //3. 注册插件下载回调
                PluginFileDownloadManager.INSTANCE.setPluginDownloadListener(pluginDownloadListener);
                //4. 判断是有属于自己的下载任务,前提是这个线程在service启动之后只会走一次
                if (TextUtils.isEmpty(pluginId)) {
                    byte status = PluginFileDownloadManager.INSTANCE.addDownloadTasks(pluginInfos, null);
                    notifyListener(false, pluginId, 0, status);
                } else {
                    //由于点击下载，会先将所有plugin全部判断并添加进downloader，所以第一个目标plugin的状态可能已经下载完成，所以这里进行判断
                    boolean exist = ReactUtils.checkJsBundleFileExistFromSD(ALHPluginDownloadService.this, pluginId);
                    if (exist) {
                        notifyListener(true, pluginId, 0, FileDownloadStatus.completed);
                    } else {
                        int status = PluginFileDownloadManager.INSTANCE.addDownloadTasks(pluginInfos, pluginId);
                        notifyListener(false, pluginId, 0, status);
                    }
                }
            }


            @Override
            public void onError(String e) {
                apiRequestStatus = STATUS_REQUEST_END;
                log("requestUpdateInfo onError:" + e);
                notifyListener(false, pluginId, 0, FileDownloadStatus.error);
                serviceFinished();
            }
        });

    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        pluginDownloadListener = null;
    }


    public class PluginDownloadListener implements DownloadListener {
        @Override
        public void onComputerTask(String pluginId, int progress, boolean isSuccess, byte status) {
            ALog.e("PluginDownloadListener", "pluginId:" + pluginId + ";progress=" + progress + ";isSuccess:" + isSuccess + ";status=" + status);
            notifyListener(isSuccess, pluginId, progress, status);
        }
    }

    private void log(String msg) {
        RNLogger.i(TAG + msg);
    }
}
